package org.penguin.study.bk.file;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * @author chengyinghua
 */
@Slf4j
@RestController
@RequestMapping("/file")
public class FileRestController {
    static Map<String, String> map = null;

    static {
        map = new HashMap<>();
        map.put("FFD8FF", "jpg");
        map.put("89504E", "png");
        map.put("474946", "gif");
        map.put("524946", "webp");
        map.put("000001", "ico");
        map.put("424D36", "bmp");
        map.put("00000A", "tga");
        map.put("49492A", "tif");
    }

    private static String bytesToHexString(byte[] src) {
        StringBuilder stringBuilder = new StringBuilder();
        if (src == null || src.length <= 0) {
            return null;
        }
        for (int i = 0; i < src.length; i++) {
            int v = src[i] & 0xFF;
            String hv = Integer.toHexString(v);
            if (hv.length() < 2) {
                stringBuilder.append(0);
            }
            stringBuilder.append(hv);
        }
        return stringBuilder.toString();
    }

//    /**
//     * 获取文件头
//     *
//     * @param src
//     * @return
//     */
//    private static String bytesToHexString(byte[] src) {
//        StringBuilder stringBuilder = new StringBuilder();
//        if (null == src || src.length < 1) {
//            return null;
//        }
//
//        for (byte b : src) {
//            int v = b & 0xFF;
//            String hv = Integer.toHexString(v);
//            if (hv.length() < 2) {
//                stringBuilder.append(0);
//            }
//            stringBuilder.append(hv);
//        }
//        return stringBuilder.toString();
//    }

    private static String checkType(String code) {
        return map.get(code);
    }

    /**
     * 获得文件后缀
     *
     * @param file
     * @return
     */
    public static String getType(File file) {
        String type = "";
        FileInputStream fileInputStream = null;
        try {
            fileInputStream = new FileInputStream(file);
            byte[] b = new byte[3];
            fileInputStream.read(b, 0, b.length);
            String code = bytesToHexString(b);
            code = code.toUpperCase();
            type = checkType(code);
        } catch (Exception e) {
            log.error("获取文件格式异常");
        } finally {
            if (fileInputStream != null) {
                try {
                    fileInputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return type;
    }

    @Value("${upload.filePath}")
    private String uploadFilePath;

    @PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public String fileUpload(@RequestParam("file") MultipartFile file) throws
            IOException {
        File directory = new File(uploadFilePath);
        if (!directory.exists()) {
            directory.mkdirs();
        }
        if (!directory.canWrite()) {
            return uploadFilePath + " is readonly";
        }

        if (!directory.isDirectory()) {
            return uploadFilePath + " is not a directory";

        }
        File convertFile = new File(uploadFilePath, file.getOriginalFilename());
        log.debug("文件类型: " + getType(convertFile));
        convertFile.createNewFile();
        FileOutputStream fout = new FileOutputStream(convertFile);
        fout.write(file.getBytes());
        fout.close();
        return "File is upload successfully";
    }

    @GetMapping(value = "/download")
    public ResponseEntity<Object> downloadFile(String fileName) throws IOException {
        String filename = uploadFilePath + "/" + fileName;
        File file = new File(filename);
        InputStreamResource resource = new InputStreamResource(new FileInputStream(file));
        HttpHeaders headers = new HttpHeaders();
        headers.add("Content-Disposition", String.format("attachment;filename=%s", file.getName()));
        headers.add("Cache-Control", "no-cache, no-store, mustrevalidate");
        headers.add("Pragma", "no-cache");
        headers.add("Expires", "0");
        ResponseEntity<Object> responseEntity =
                ResponseEntity.ok().headers(headers).contentLength(file.length()).contentType(MediaType.parseMediaType("application/txt")).body(resource);
        return responseEntity;
    }
}
